#include "Lily_help.h"

int __nameTuple_compare(const void *a, const void *b)
{
    return ((int32_t)((_NameTuple)a)->hashCode) - ((int32_t)((_NameTuple)b)->hashCode);
}

int public_obj(Li_List list, void *new_obj)
{
    _NameTuple new_cmd = (_NameTuple)new_obj;
    new_cmd->hashCode = getHashCodeS(new_cmd->name);
    if (list_add(list, new_cmd) < 0)
        return -1;
    list_sort(list, __nameTuple_compare);
    return list_find_binary(list, new_cmd, __nameTuple_compare);
}

int search_obj(Li_List list, const char *name)
{
    if (!list || !name)
        return -1;
    HASH _hc = getHashCodeS(name);
    _NameTuple_t obj = {(char *)name, _hc};
    int ind = list_find_binary(list, &obj, __nameTuple_compare);
    if (ind < 0)
        return -1;
    _NameTuple got = (_NameTuple)list_index(list, ind);
    if (!strcmp(got->name, name))
        return ind;
    // search upwards
    int i = ind - 1;
    while (i >= 0)
    {
        got = (_NameTuple)list_index(list, i);
        if (got->hashCode != _hc)
            break;
        if (!strcmp(got->name, name))
            return i;
        i--;
    }
    // search downwards
    i = ind + 1;
    while (i < list->count)
    {
        got = (_NameTuple)list_index(list, i);
        if (got->hashCode != _hc)
            break;
        if (!strcmp(got->name, name))
            return i;
        i++;
    }
    return -1;
}

int ln_list_add(Ln_head list, Ln_list new_node)
{
    if (!list || !new_node)
        return -1;
    new_node->next = list->next;
    list->next = new_node;
    return 0;
}
int ln_list_add_tail(Ln_head list, Ln_list new_node)
{
    if (!list || !new_node)
        return -1;
    Ln_list p = list;
    while (p->next)
        p = p->next;
    p->next = new_node;
    new_node->next = NULL;
    return 0;
}
int ln_list_remove(Ln_head list, Ln_list node)
{
    if (!list || !node)
        return -1;
    Ln_list p = list;
    while (p->next)
    {
        if (p->next == node)
        {
            p->next = node->next;
            return 0;
        }
        p = p->next;
    }
    return -1;
}
int ln_list_move(Ln_head list, Ln_list node)
{
    if (!list || !node)
        return -1;
    Ln_list p = list;
    while (p->next)
    {
        if (p->next == node)
        {
            p->next = node->next;
            node->next = list->next;
            list->next = node;
            return 0;
        }
        p = p->next;
    }
    return -1;
}
int ln_list_move_tail(Ln_head list, Ln_list node)
{
    if (!list || !node)
        return -1;
    Ln_list p = list;
    char check = 0;
    while (p->next)
    {
        if (p->next == node)
        {
            p->next = node->next;
            p = node;
            check = 1;
            continue;
        }
        p = p->next;
    }
    if (!check)
        return -1;
    if (p == node)
        return 0;
    p->next = node;
    node->next = NULL;
    return 0;
}
